﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace CodePlex.Resourceful.Microsoft.Azure
{



//<EnumerationResults ContainerName="http://myaccount.blob.core.windows.net/mycontainer">
//  <Prefix>string-value</Prefix>
//  <Marker>string-value</Marker>
//  <MaxResults>int-value</MaxResults>
//  <Delimiter>string-value</Delimiter>
//  <Blobs>
//    <Blob>
//      <Url>blob-address</Url>
//      <LastModified>date/time-value</LastModified>
//      <Etag>etag</Etag>
//      <Size>size-in-bytes</Size>
//      <ContentType>blob-content-type</ContentType>
//      <ContentEncoding />
//      <ContentLanguage />
//    </Blob>
//  </Blobs>
//  <BlobPrefix>
//    <Name>blob-prefix</Name>
//  </BlobPrefix>
//  <NextMarker />
//</EnumerationResults>
    public class BlobListing
    {
        private readonly Uri _containerUri;

        private readonly string _prefix;
        private readonly string _marker;
        private readonly int? _maxResults;
        private readonly string _delimiter;

        private readonly List<BlobInfo> _blobs;
        private readonly List<string> _blobPrefixes;

        private readonly string _nextMarker;

        public BlobListing(Uri containerUri, string prefix, string marker, int? maxResults, string delimiter,
            IEnumerable<BlobInfo> blobs, IEnumerable<string> blobPrefixes, string nextMarker)
        {
            _containerUri = containerUri;
            _prefix = prefix;
            _marker = marker;
            _maxResults = maxResults;
            _delimiter = delimiter;
            _blobs = new List<BlobInfo>(blobs);
            _blobPrefixes = new List<string>(blobPrefixes);
            _nextMarker = nextMarker;
        }

        public Uri ContainerUri { get { return _containerUri; } }
        public string Prefix { get { return _prefix; } }
        public string Marker { get { return _marker; } }
        public int? MaxResults { get { return _maxResults; } }
        public string Delimiter { get { return _delimiter; } }

        public IEnumerable<BlobInfo> Blobs { get { return _blobs; } }
        public IEnumerable<string> BlobPrefixes { get { return _blobPrefixes; } }

        public string NextMarker { get { return _nextMarker; } }

        public bool IsEmpty { get { return _blobs.Count == 0 && _blobPrefixes.Count == 0; } }


        public static BlobListing Parse(XmlReader reader)
        {
            Uri containerUri = default(Uri);
            string prefix = default(string);
            string marker= default(string);
            int? maxResults = default(int?);
            string delimiter = default(string);
            List<BlobInfo> blobs = new List<BlobInfo>();
            List<string> blobPrefixes = new List<string>();
            string nextMarker = default(string);


            

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.LocalName == "EnumerationResults")
                    {
                        containerUri = new Uri(reader.GetAttribute("ContainerName"));
                    }
                    if (reader.LocalName == "Prefix" && !reader.IsEmptyElement)
                    {
                        prefix = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "Marker" && !reader.IsEmptyElement)
                    {
                        marker = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "MaxResults" && !reader.IsEmptyElement)
                    {
                        maxResults = int.Parse(Utils.ReadString(reader));
                    }
                    if (reader.LocalName == "Delimiter" && !reader.IsEmptyElement)
                    {
                        delimiter = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "Blob")
                    {
                        BlobInfo blob = BlobInfo.Parse(reader);
                        blobs.Add(blob);
                    }
                    if (reader.LocalName == "BlobPrefix")
                    {
                        while (reader.Read())
                        {
                            if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "Name")
                            {
                                blobPrefixes.Add(Utils.ReadString(reader));
                                break;
                            }
                        }
                    }
                    if (reader.LocalName == "NextMarker" && !reader.IsEmptyElement)
                    {
                        nextMarker = Utils.ReadString(reader);
                    }

                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "EnumerationResults")
                {
                    return new BlobListing(containerUri, prefix, marker, maxResults, delimiter, blobs, blobPrefixes, nextMarker);
                }

            }

            throw CodePlexException.Format("Failed to parse EnumerationResults.");
        }
    }

    public class BlobInfo
    {


        
        private readonly Uri _blobUri;
        private readonly string _lastModified;
        private readonly string _etag;
        private readonly long _size;
        private readonly string _contentType;
        private readonly string _contentEncoding;
        private readonly string _contentLanguage;

        public BlobInfo(Uri blobUri, string lastModified, string etag, long size,
            string contentType, string contentEncoding, string contentLanguage)
        {
            _blobUri = blobUri;
            _lastModified = lastModified;
            _etag = etag;
            _size = size;
            _contentType = contentType;
            _contentEncoding = contentEncoding;
            _contentLanguage = contentLanguage;
        }

       

        public Uri BlobUri
        {
            get
            {
                return _blobUri;
            }
        }
        public string LastModified
        {
            get
            {
                return _lastModified;
            }
        }
        public string Etag
        {
            get
            {
                return _etag;
            }
        }
        public long Size
        {
            get
            {
                return _size;
            }
        }
        public string ContentType
        {
            get
            {
                return _contentType;
            }
        }
        public string ContentEncoding
        {
            get
            {
                return _contentEncoding;
            }
        }
        public string ContentLanguage
        {
            get
            {
                return _contentLanguage;
            }
        }




        //    <Url>blob-address</Url>
        //    <LastModified>date/time-value</LastModified>
        //    <Etag>etag</Etag>
        //    <Size>size-in-bytes</Size>
        //    <ContentType>blob-content-type</ContentType>
        //    <ContentEncoding />
        //    <ContentLanguage />
        public static BlobInfo Parse(XmlReader reader)
        {

            Uri blobUri = default(Uri);
            string lastModified = default(string);
            string etag = default(string);
            long size = default(long);
            string contentType = default(string);
            string contentEncoding = default(string);
            string contentLanguage = default(string);

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {

                    if (reader.LocalName == "Url" && !reader.IsEmptyElement)
                    {
                        blobUri = new Uri(Utils.ReadString(reader));
                    }
                    if (reader.LocalName == "LastModified" && !reader.IsEmptyElement)
                    {
                        lastModified = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "Etag" && !reader.IsEmptyElement)
                    {
                        etag = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "Size" && !reader.IsEmptyElement)
                    {
                        size = long.Parse(Utils.ReadString(reader));
                    }
                    if (reader.LocalName == "ContentType" && !reader.IsEmptyElement)
                    {
                        contentType = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "ContentEncoding" && !reader.IsEmptyElement)
                    {
                        contentEncoding = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "ContentLanguage" && !reader.IsEmptyElement)
                    {
                        contentLanguage = Utils.ReadString(reader);
                    }
                   
                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "Blob")
                {
                    return new BlobInfo(blobUri, lastModified, etag, size, contentType, contentEncoding, contentLanguage);
                }

            }

            throw CodePlexException.Format("Failed to parse Blob.");
        }



    }

    public class ContainerListing
    {
        private readonly string _accountName;
        private readonly List<ContainerInfo> _containers;

        public ContainerListing(string accountName,IEnumerable<ContainerInfo> containers)
        {
            _accountName = accountName;
            _containers = new List<ContainerInfo>(containers);
        }

        public IEnumerable<ContainerInfo> Containers
        {
            get
            {
                return _containers;
            }
        }

        public static ContainerListing Parse(XmlReader reader)
        {
            string accountName = default(string);
            List<ContainerInfo> containers = new List<ContainerInfo>();

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.LocalName == "AccountName" && !reader.IsEmptyElement)
                    {
                        accountName = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "Container")
                    {
                        ContainerInfo container = ContainerInfo.Parse(reader);
                        containers.Add(container);
                    }
                  

                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "EnumerationResults")
                {
                    return new ContainerListing(accountName, containers);
                }

            }

            throw CodePlexException.Format("Failed to parse EnumerationResults.");
        }

    }

    public class ContainerInfo
    {
        private readonly string _name;
        private readonly string _url;
        private readonly string _lastModified;
        private readonly string _etag;

        public ContainerInfo(string name, string url, string lastModified, string etag)
        {
            _name = name;
            _url = url;
            _lastModified = lastModified;
            _etag = etag;
        }

        public string Name
        {
            get
            {
                return _name;
            }
        }

        public string Url
        {
            get
            {
                return _url;
            }
        }
        public string LastModified
        {
            get
            {
                return _lastModified;
            }
        }
        public string Etag
        {
            get
            {
                return _etag;
            }
        }




        public static ContainerInfo Parse(XmlReader reader)
        {
            string name = default(string);
            string url = default(string);
            string lastModified = default(string);
            string etag = default(string);

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.LocalName == "Name" && !reader.IsEmptyElement)
                    {
                        name = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "Url" && !reader.IsEmptyElement)
                    {
                        url = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "LastModified" && !reader.IsEmptyElement)
                    {
                        lastModified = Utils.ReadString(reader);
                    }
                    if (reader.LocalName == "Etag" && !reader.IsEmptyElement)
                    {
                        etag = Utils.ReadString(reader);
                    }
                   
                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "Container")
                {
                    return new ContainerInfo(name, url, lastModified, etag);
                }

            }

            throw CodePlexException.Format("Failed to parse ContainerInfo.");
        }
    }
}
